/**
 * Created with PyCharm.
 * User: jay.han
 * Date: 5/22/13
 * Time: 4:30 PM
 view中我们遵循下面的约定：
 angularjs中定义resource url只保留get，post两个方法，在get和post基础上
 添加action来区分操作.基本上每个资源都对应单个和多个的操作url，url定义规范：
 datacenter
 个体操作：/api/datacenter/:id/:action
 批量操作：/api/datacenters/:action
 */

angular.module('CvirtServices', ['ngResource'])
    .config(function ($httpProvider,$compileProvider) {
        $httpProvider.responseInterceptors.push('loadingInterceptor');
        var spinnerFunction = function (data, headersGetter) {
            return data;
        };
        $httpProvider.defaults.transformRequest.push(spinnerFunction);

        $compileProvider.urlSanitizationWhitelist(/^\s*(https?|spice|mailto):/);
    })
    //register the interceptor as a service, intercepts ALL angular ajax http calls
    .factory('loadingInterceptor', function ($q, $window, $rootScope) {
        return function (promise) {
            $rootScope.polling = !$rootScope.noload;
            $rootScope.network_error = false;
            return promise.then(function (response) {
                $rootScope.polling = false;
                return response;
            }, function (response) {
                $rootScope.polling = false;
                $rootScope.network_error = true;
                return $q.reject(response);
            });
        };
    })
    .factory('License', function ($resource) {
        return $resource('/api/license/:id/', {id: '@id'}, {
            "get": {method: 'GET', url: '/api/license'},
            "update": {method: 'POST', url: "/api/license/update"}
        });
    })
    .factory('DataCenter', function ($resource, TokenHandler) {
        var resource = $resource('/api/datacenter/:id/:action', {id: '@id'}, {
            list: {method: 'GET', isArray: true, url: "/api/datacenters"},
            create: {method: 'POST', url: "/api/datacenters/create"},
            get: {method: 'GET'},
            hosts: {method: 'GET', params: {action: 'hosts'}},

            vms: {method: 'GET', params: {action: 'vms'}},
            networks: {method: 'GET', params: {action: 'networks'}},
            storages: {method: 'GET', params: {action: 'storages'}},
            tasks: {method: 'GET', params: {action: 'tasks'}},
            schedule_tasks: {method: 'GET', params: {action: 'schedule_tasks'}},
            backups: {method: 'GET', params: {action: 'backups'}},

            add_schedule_task: {method: 'POST', url: '/api/datacenter/:id/add_schedule_task'},
            delete_schedule_task: {method: 'POST', url: '/api/datacenter/:id/delete_schedule_task'},
            update_schedule_task: {method: 'POST', params: {action: 'update_schedule_task'}},
            q:{method:'GET',url:'/api/datacenters/q',isArray:true}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["list", "create", "get", "hosts", "vms", "networks",
                "storages", "tasks", "schedule_tasks", "backups", "add_schedule_task", "update_schedule_task", "delete_schedule_task"]);

        return resource;
    })
    .factory('DataCenterEvent', function ($resource, TokenHandler) {
        var resource = $resource('/api/datacenter/:data_center_id/events/:id', {data_center_id: '@data_center_id', id: '@id'}, {
            get: {method: 'GET'},
            query: {method: 'GET', isArray: true},
            delete_all: {method: 'POST', url: '/api/datacenter/:data_center_id/events/delete_all'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["get", "query", "delete_all"]);

        return resource;
    })
    .factory('Cluster', function ($resource, TokenHandler) {
        var resource = $resource('/api/cluster/:id/:action', {id: '@id'}, {
            get: {method: 'GET'},
            hosts: {method: 'GET', url: "/api/cluster/:id/hosts"},
            vms: {method: 'GET', url: "/api/cluster/:id/vms"},
            networks: {method: 'GET', url: "/api/cluster/:id/networks"},
            templates: {method: 'GET', url: "/api/cluster/:id/templates"},
            storages: {method: 'GET', url: "/api/cluster/:id/storages"},
            backups: {method: 'GET', isArray: true, url: "/api/cluster/:id/backups"},
            backup_strategy: {method: 'GET', isArray: true, url: "/api/cluster/:id/backup_strategy"},
            backup_status: {method: 'GET', url: "/api/cluster/:id/backup_status"},
            list: {method: 'GET', isArray: true, url: "/api/clusters/"},
            create: {method: 'POST', url: "/api/clusters/create"},
            delete: {method: 'POST', params: {action: 'delete'}},
            vdisks: {method: 'GET', params: {action: 'vdisks'}},
            'delete_disk': {method: 'POST', params: {action: 'delete_disk'}},
            'add_dissociate_disk': {method: 'POST', params: {action: 'add_dissociate_disk'}},
            'update_dissociate_disk': {method: 'POST', params: {action: 'update_dissociate_disk'}}

        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["get", "hosts", "vms", "networks", "templates", "storages",
                "backups", "backup_strategy", "backup_status", "list", "create",'delete_disk',
            'add_dissociate_disk','update_dissociate_disk','delete']);

        return resource;
    })
    .factory('VM', function ($resource, TokenHandler) {
        var resource = $resource('/api/vm/:id/:action', {id: '@id', backup_id: '@backup_id'}, {
            'create': {method: 'POST', url: '/api/vms/create'},
            'list': {method: 'GET', url: '/api/vms'},
            'status': {method: 'GET', isArray: true, url: '/api/vms/status'},
            'authcheck': {method: 'GET', isArray: true, url: '/api/vms/authcheck'},
            'update': {method: 'POST', url: '/api/vm/:id/update'},
            'delete': {method: 'POST', url: '/api/vms/delete'},
            'save_template': {method: 'POST', url: '/api/vm/:id/save_as_template'},
            'migrate': {method: 'POST', url: '/api/vm/:id/migrate'},
            'hibernate': {method: 'POST', url: '/api/vms/hibernate'},
            'suspend': {method: 'POST', url: '/api/vms/suspend'},
            'unsuspend': {method: 'POST', url: '/api/vms/unsuspend'},
            'start': {method: 'POST', url: '/api/vms/start'},
            'shutdown': {method: 'POST', url: '/api/vms/shutdown'},
            'soft_shutdown': {method: 'POST', url: '/api/vms/soft_shutdown'},
            'reboot': {method: 'POST', url: '/api/vms/reboot'},
            'snapshot': {method: 'POST', url: '/api/vm/:id/snapshot'},
            'snapshot_restore': {method: 'POST', url: '/api/vm/:id/snapshot_restore'},
            'snapshot_list': {method: 'GET', url: '/api/vm/:id/snapshot_list'},
            'delete_disk': {method: 'POST', url: '/api/vm/:id/delete_disk'},
            'update_disk': {method: 'POST', url: '/api/vm/:id/update_disk'},
            'add_disk': {method: 'POST', url: '/api/vm/:id/add_disk'},
            'current_cpu': {method: 'GET', params: {action: 'current_cpu'}},
            'current_memory': {method: 'GET', params: {action: 'current_memory'}},
            'current_traffic': {method: 'GET', params: {action: 'current_traffic'}},
            'snapshot_delete': {method: 'POST', url: '/api/vm/:id/snapshot_delete'},
            'interfaces': {method: 'GET', isArray: true, url: '/api/vm/:id/interfaces'},
            'attach_disk': {method: 'POST', url: '/api/vm/:id/attach_disk'},
            'screen_shot': {method: 'POST', url: '/api/vm/:id/screen_shot'},
            'clone': {method: 'POST', url: '/api/vm/:id/clone'},
            'reset_backup': {method: 'POST', url: '/api/vms/:id/backups/:backup_id/reset'}

        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["create", "list", "status", "update", "delete", "save_template",
                "migrate", "hibernate", "suspend", "unsuspend", "start", "shutdown",
                "soft_shutdown", "reboot", "snapshot", "snapshot_restore", "snapshot_list",
                "delete_disk", "update_disk", "add_disk", "current_cpu", "current_memory", "current_traffic",
                "snapshot_delete", "interfaces", "reset_backup", "attach_disk", "screen_shot","clone"]);

        return resource;
    })
    .factory('Host', function ($resource, TokenHandler) {
        var resource = $resource('/api/host/:id/:action', {id: '@id'}, {
            "list": {method: 'GET', url: '/api/hosts/'},
            "remove": {method: 'POST', params: {action: 'remove'}},
            'status': {method: 'GET', isArray: true, url: '/api/hosts/status/'},
            'vms': {method: 'GET', params: {action: 'vms'}},
            'update': {method: 'POST', params: {action: 'update'}},
            'activate': {method: 'POST', params: {action: 'activate'}},
            'maintain': {method: 'POST', params: {action: 'maintain'}},
            'start': {method: 'POST', params: {action: 'start'}},
            'shutdown': {method: 'POST', params: {action: 'shutdown'}},
            'reboot': {method: 'POST', params: {action: 'reboot'}}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["list", "remove", "status", "vms", "update", "activate",
                "maintain", "start", "shutdown", "reboot"]);

        return resource;
    })
    .factory('Monitor', function ($resource, TokenHandler) {
        var resource = $resource('/api/monitor/:id', {id: '@id'}, {
            'do_graph': {method: 'POST', url: '/api/monitor/do_graph'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["do_graph"]);

        return resource;
    })
    .factory('Template', function ($resource, TokenHandler) {
        var resource = $resource('/api/templates/:id', {id: '@id'}, {
            'delete': {method: 'GET', url: '/api/template/:id/delete'},
            'delete_all': {method: 'POST', url: '/api/templates/delete_all'},
            'list': {method: 'GET', url: '/api/templates'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["delete", "delete_all", "list"]);

        return resource;
    })
    .factory('Activity', function ($resource, TokenHandler) {
        var resource = $resource('/api/activities', {}, {
            'list': {method: 'get', isArray: true},
            'alives': {method: 'get', isArray: true, url: '/api/activities/alives'},
            'status': {method: 'POST', isArray: true, url: '/api/activities/status'}
        });
        resource = TokenHandler.wrapActions(resource,
            ["list", "alives", "status"]);
        return resource
    })
    .factory('SecurityRule', function ($resource, TokenHandler) {
        var resource = $resource('/api/security_rules/:id', {id: '@id'}, {
            'list': {method: 'GET', url: '/api/security_rules'},
            'update': {method: 'POST', url: "/api/security_rules/update"},
            'create': {method: 'POST', url: '/api/security_rules/create'},
            'delete_all': {method: 'POST', url: '/api/security_rules/delete_all'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["list", "update", "create", "delete_all"]);

        return resource;
    })
    .factory('SecurityGroup', function ($resource, TokenHandler) {
        var resource = $resource('/api/security_groups/:id', {id: '@id'}, {
            'list': {method: 'GET', url: '/api/security_groups'},
            'update': {method: 'POST', url: "/api/security_groups/update"},
            'create': {method: 'POST', url: '/api/security_groups/create'},
            'get': {method: 'GET'},
            'relate_vm': {method: 'POST', url: '/api/security_groups/:id/relate_vm'},
            'delete_all': {method: 'POST', url: '/api/security_groups/delete_all'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["list", "update", "create", "get", "relate_vm", "delete_all"]);

        return resource;
    })
    .factory('Network', function ($resource, TokenHandler) {
        var resource = $resource('/api/network/:id/:action', {id: '@id'}, {
            'create': {method: 'POST', url: "/api/networks/create"},
            'update': {method: 'POST', params: {action: 'update'}},
//            'status': {method: 'POST', isArray: true, url: '/api/networks/status'},
            'delete': {method: 'POST', params: {action: 'delete'}},
            'fixedips': {method: 'GET', isArray: true, params: {action: 'fixedips'}},
            'random_mac': {method: 'GET', url: '/api/networks/random_mac'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["create", "update", "delete", "fixedips", "random_mac"]);

        return resource;
    })
    .factory('Fixedip', function ($resource, TokenHandler) {
        var resource = $resource('/api/fixedip/:id/:action', {id: '@id'}, {
            'list': {method: 'GET', url: '/api/fixedips'},
            'create': {method: 'POST', params: {action: 'create'}},
            'delete_all': {method: 'POST', url: '/api/fixedips/delete_all'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["list","create","delete_all"]);

        return resource;
    })
    .factory('Storage', function ($resource, TokenHandler) {
        var resource = $resource('/api/storage/:id/:action', {id: '@id'}, {
            'create': {method: 'POST', url: '/api/storages/create'},
            'update': {method: 'PUT'},
            'get': {method: 'GET', isArray: true, url: '/api/storages'},
            'status': {method: 'POST', params: {action: 'status'}},
            'delete': {method: 'POST', params: {action: 'delete'}},
            'isos': {method: 'GET', isArray: true, url: '/api/storages/isos'},
            'targets': {method: 'POST', url: '/api/storages/targets'},
            'luns': {method: 'POST', url: '/api/storages/luns'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["create", "update", "get", "status", "delete", "isos", "targets", "luns"]);

        return resource;
    })
    .factory('Shortcut', function ($resource, TokenHandler) {
        var resource = $resource('/api/shortcuts/:id', {id: '@id'}, {
            'status': {method: 'POST', isArray: true, url: '/api/shortcuts/status'},
            'list': {method: 'GET', url: '/api/shortcuts'},
            'delete_all': {method: 'POST', url: '/api/shortcuts/delete_all'},
            'delete': {method: 'GET', url: '/api/shortcut/:id/delete'},
            'save': {method: 'POST', url: '/api/shortcut/save'},
            'delete_from_thrd': {method: 'POST', url: '/api/shortcut/delete_from_thrd'}
        });

        resource = TokenHandler.wrapActions(resource,
            ["status", "list", "delete_all", "delete", "save", "delete_from_thrd"]);

        return resource;
    })
    .factory('Proposal', function ($resource, TokenHandler) {
        var resource = $resource('/api/proposals/:id', {id: '@id'}, {
            'update': {method: 'POST', url: '/api/proposal/:id/update'},
            'list': {method: 'GET', url: '/api/proposals'},
            'status': {method: 'POST', isArray: true, url: '/api/proposals/status'},
            'delete': {method: 'POST', url: '/api/proposals/delete'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["update", "list", "status", "delete"]);

        return resource;
    })
    .factory('Backup', function ($resource, TokenHandler) {
        var resource = $resource('/api/backups/:id', {id: '@id'}, {
            'list': {method: 'get', isArray: true, url: '/api/backups'},
            'update': {method: 'PUT'},
            'status': {method: 'GET', url: '/api/backups/status'},
            'delete_all': {method: 'POST', url: '/api/backups/delete_all'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["update", "list", "status", "delete_all"]);

        return resource;
    })
    .factory('BackupStrategy', function ($resource, TokenHandler) {
        var resource = $resource('/api/backup_strategies/:id', {id: '@id'}, {
            'update': {method: 'POST', url: "/api/backup_strategies/update"},
            'status': {method: 'POST', isArray: true, url: '/api/backup_strategies/status'},
            'create': {method: 'POST', url: "/api/backup_strategies/create"},
            'delete_all': {method: 'POST', url: '/api/backup_strategies/delete_all'},
            'list': {method: 'GET', url: '/api/backup_strategies'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["update", "list", "status", "delete_all", "create"]);

        return resource;
    })
    .factory('Platform', function ($resource, TokenHandler) {
        var resource = $resource('/api/platform/:id', {id: '@id'}, {
            'info':{method:'GET',url:'/api/platform'},
            'update_license':{method:'POST',url:'/api/platform/update_license'},
            'register_license':{method:'POST',url:'/api/platform/register_license'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
//        resource = TokenHandler.wrapActions(resource,
//            ["info", "update_license"]);

        return resource;
    })
    .factory('User', function ($resource, TokenHandler) {
        var resource = $resource('/api/user/:id/:action', {id: '@id'}, {
            'create':{method:'POST',url:'/api/users/create'},
            'list':{method:'GET',url:'/api/users'},
            'update':{method:'POST',params:{action:'update'}},
            'delete':{method:'POST',url:'/api/users/delete'},
            'active':{method:'POST',url:'/api/users/active'},
            'deny':{method:'POST',url:'/api/users/deny'},
            'attach':{method:'POST',params:{action:'attach'}}
        });

        resource = TokenHandler.wrapActions(resource,
            ["create"]);

        return resource;
    })
    .factory('ztree', function (ContextMenu) {
        function create(data, parent) {
            var tree = $.fn.zTree.getZTreeObj('search-tree');
            var parent = parent || tree.getSelectedNodes()[0];
            if (tree && parent) {
                tree.addNodes(parent, [data]);
            }
        }

        return {
            deletenode: function (id) {
                console.log('delete id ' + id + ' of treenode');
                var tree = $.fn.zTree.getZTreeObj('search-tree');
                var node = tree.getNodeByParam('id', id);
                var parent = node.getParentNode();
                tree.removeNode(node);
                tree.selectNode(parent);
            },
            addcluster: function (data) {
                var cluster = {
                    icon: "/static/images/cluster.png",
                    children: []
                }
                cluster = angular.extend(cluster, data);
                cluster.id = 'c' + cluster.id;
                if (!this.get_node_by_id("c" + cluster.id)) {
                    create(cluster);
                }

            },
            get_node_by_id: function (id) {
                var tree = $.fn.zTree.getZTreeObj('search-tree');
                return tree.getNodeByParam('id', id, null);
            },
            addvm: function (data, host_id) {
                var vm = {
                    children: []
                }
                vm = angular.extend(vm, data);
                var id = vm.id;
                vm.id = 'v' + id;
                vm.did = id;
                vm.type = 'vm';
                if (!this.get_node_by_id("v" + vm.id)) {
                    create(vm, this.get_node_by_id("h" + host_id));
                }
            },
            get_select_node_data: function () {
                var tree = $.fn.zTree.getZTreeObj('search-tree');
                var nodes = tree.getSelectedNodes();
                if (nodes.length > 0) {
                    return nodes[0];
                }

            },
            edit_node_name: function (id, name) {
                var tree = $.fn.zTree.getZTreeObj('search-tree');
                var node = tree.getNodeByParam('id', id, null);
                if (node) {
                    node.name = name;
                    tree.updateNode(node);
                }
            },
            addhost: function (data, cluster_id) {
                var host = {
                    icon: "/static/images/host.png",
                    children: []
                }
                host = angular.extend(host, data);
                host.id = "h" + host.id;
                if (!this.get_node_by_id("h" + host.id)) {
                    create(host, this.get_node_by_id("c" + cluster_id));
                }

            }
        };
    })
    .factory('GlobalConfig', function ($resource, TokenHandler) {
        var resource = $resource('/api/globalconfigs/:id', {id: '@id'}, {
            'get': {method: 'get', isArray: true, url: '/api/globalconfigs'},
            'update': {method: 'post', isArray: true, url: '/api/globalconfigs/updatesettings'}
        });

        // 在请求的后面添加token，如果不需要将下面的两行代码删除即可
        resource = TokenHandler.wrapActions(resource,
            ["get", "update"]);

        return resource;
    })
    .factory('Login', function ($resource, TokenHandler) {

        var resource = $resource('/api-token-auth', {}, {
            'login': {method: 'POST'},
            'checkLogin': {method: 'GET', url: '/checklogin'}
        });

        return resource;
    })
    .factory('Logout', function ($resource, TokenHandler) {

        var resource = $resource('/logout', {}, {
            'logout': {method: 'GET'}
        });

        return resource;
    })
    .factory('TokenHandler', function (Util, $http, $cookieStore) {

        var tokenHandler = {};
//        var token;
//
//        tokenHandler.set = function(newToken) {
//            token = newToken;
//        };
//
//        tokenHandler.get = function() {
//            token = $cookieStore.get('token');
//            return token;
//        };

        // wraps given actions of a resource to send auth token
        // with every request
        tokenHandler.wrapActions = function (resource, actions) {

            //不能在wrapaction时检查cookie，这样会导致service注入时就会触发
//             if (!tokenHandler.get()) {
//                 window.location.href = "/web/login.html";
//             }

            // copy original resource
            var wrappedResource = resource;
            // loop through actions and actually wrap them
            for (var i = 0; i < actions.length; i++) {
                tokenWrapper(wrappedResource, actions[i]);
            }
            ;
            // return modified copy of resource
            return wrappedResource;
        };

        // wraps resource action to send request with auth token
        var tokenWrapper = function (resource, action) {

            //这里是全局设置，只要执行过一次，http请求头部就会有token信息，所以directive中可以使用
            //$http请求数据。因为app.js注入了activity resource，注入之前已经执行了tokenwrap了
            $http.defaults.headers.get = {Authorization: "Token"};
            $http.defaults.headers.post['Authorization'] = "Token " + $cookieStore.get('token');
            $http.defaults.headers.get['Authorization'] = "Token " + $cookieStore.get('token');

            // copy original action
            resource['_' + action] = resource[action];
            // create new action wrapping the original
            // and sending token
            resource[action] = function (data, success, error) {

                return resource['_' + action](
                    // call action with provided data and
                    // appended access_token
                    angular.extend({}, data || {},
                        {}),
                    success,
                    function (e) {
                        e.data = Util.decode_error_msg(e.data);
                        var errorfunc = error || function (e) {
                            if (e.data) Util.alert(e.data)
                        };
                        //如果token过期或者没有token则自动转跳到登录页面
                        if (e.data&&e.data.detail) {
                            if (e.data.detail.indexOf('Token has expired') != -1 || e.data.detail.indexOf('Invalid token') != -1) {
//                                alert(e.data.detail);
                                alert("认证已过期");
                                window.location.href = "/web/login.html";
                            }
                            if(e.data.detail.indexOf('NoLicenseExist')!=-1||e.data.detail.indexOf('licenseExpire')!=-1||e.data.detail.indexOf('licenseExaust')!=-1){
                                if(window.location.href.indexOf("/web/license.html") == -1){
                                    window.location.href = "/web/license.html";
                                }
                            }
                        } else {
                            errorfunc(e);
                        }
                    }
                );
            };
        }

        return tokenHandler;
    });
